package com.mes.schedule.manager;

import java.util.Comparator;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.mes.schedule.domain.SOperationTask;
import com.mes.schedule.domain.ScheduleScheme;
import com.mes.schedule.manager.iface.IReadyTaskManager;
/**
 * 对可调度任务队列进行管理的类
 */
@Component("readyTaskManager")
@Transactional
public class ReadyTaskManager implements IReadyTaskManager{
	private final static Log log = LogFactory
			.getLog(ReadyTaskManager.class);
	 
	protected ScheduleOperationTaskManager scheduleOperationTaskManager;


	public ScheduleOperationTaskManager getScheduleOperationTaskManager() {
		return scheduleOperationTaskManager;
	}


	public void setScheduleOperationTaskManager(
			ScheduleOperationTaskManager scheduleOperationTaskManager) {
		this.scheduleOperationTaskManager = scheduleOperationTaskManager;
	}



	public  synchronized void add(ScheduleScheme scheme, SOperationTask operationTask) {
		addTask(scheme.getReadyTaskS(), operationTask);

	}

	public synchronized void addTask(TreeSet<SOperationTask> readyTaskS,
			SOperationTask operationTask) {
		if (log.isDebugEnabled()) {

			if (operationTask.getDrawingId().equals("114122687")
					&& operationTask.getBatchNum().equals("19AG1241分02")
					&& operationTask.getOperationIdDesc().equals("88")) {
				log.debug(operationTask);

			}
		}
		if (operationTask.getAssignState() != SOperationTask.ASSNSTATE_WAITING)
			return;
		if (operationTask.isFinished())
			return;
		// todo,对没有调度的零件任务进行处理
//		SPartTask parentTask = operationTask.getParentTask();

		// lqm
		// 暂时采用零件的静态松弛
		// schedulePartTaskManager.calcSlack(parentTask, operationTask);
		readyTaskS.add(operationTask);

	}

	public void clear(ScheduleScheme scheme) {

		scheme.getReadyTaskS().clear();

	}

	public synchronized SOperationTask getFirstTask(ScheduleScheme scheme) {
		TreeSet<SOperationTask> readyTaskS = scheme.getReadyTaskS();
		// if (log.isDebugEnabled()) {
		// Iterator iter = readyTaskS.iterator();
		// while (iter.hasNext()) {
		// SOperationTask o = (SOperationTask) iter.next();
		// log.debug(o + "锁定" + o.getLocked() + " 优先级" + o.getPriority()
		// + " 松弛率 " + o.getSlackFactor());
		// }
		// }
		return readyTaskS.first();
	}

	public synchronized int getSize(ScheduleScheme scheme) {
		return scheme.getReadyTaskS().size();
	}

	public void initSortRule(ScheduleScheme scheme) {

		// 任务自排序规则
		TreeSet<SOperationTask> readyTaskS = new TreeSet<SOperationTask>(
				new Comparator<SOperationTask>() {
					public int compare(SOperationTask operTask1,
							SOperationTask operTask2) {
						if (operTask1.equals(operTask2))
							return 0;
						int i = -1;
						// 都是锁定的情况下
						// 优先级越大表示越不重要
						// 同等优先级松弛率越大表示越不重要
						if (!operTask1.isStarted()) {//对于两个都是已开始的情况不考虑
							if (operTask1.getCalLocked() == operTask2.getCalLocked()) {

								if (operTask1.getPriority() > operTask2
										.getPriority())
									i = 1;
								else if (operTask1.getPriority().compareTo(
										operTask2.getPriority()) == 0) {

									if (operTask1.getDelayCost() < operTask2
											.getDelayCost())
										i = 1;
									else if (operTask1
											.getDelayCost()
											.compareTo(operTask2.getDelayCost()) == 0) {
										// todo
										// 应该增加是否有父任务的判断
										// lqm，先采用零件松弛
										// 将来应该采用更合理的动态松弛
										if (operTask1.getSlackFactor() > operTask2
												.getSlackFactor())
											i = 1;
									}
								}

							} else if (operTask2.getCalLocked() == 1)// 如果任务2锁定
								i = 1;
						}
						return i;
					}
				});

		scheme.setReadyTaskS(readyTaskS);

	}

	// todo
	// 就是一个顺序

	public void init(ScheduleScheme scheme) {

		initSortRule(scheme);

		TreeSet<SOperationTask> readyTaskS = scheme.getReadyTaskS();
		for (SOperationTask operationTask : scheme
				.getScheduleOperationTasks()) {
			if (operationTask.getCalLocked() == 1) {
				// 将锁定任务也放入这个集合中
				// 锁定任务暂时不管其前后工序约束
				// todo，应该有一张报表来分析这种违反约束现象
				// 先准备
				addTask(readyTaskS, operationTask);
			} else {
				if (operationTask.getPredLinkSet().size() == 0) {// 前置任务为空
					// 先准备
					addTask(readyTaskS, operationTask);

				}
			}
		}

	}

	public synchronized  void remove(ScheduleScheme scheme, SOperationTask operationTask) {
		if (scheme.getReadyTaskS().contains(operationTask))
			scheme.getReadyTaskS().remove(operationTask);

	}

	public synchronized boolean isEmpty(ScheduleScheme scheme) {
		// TODO Auto-generated method stub
		return scheme.getReadyTaskS().isEmpty();
	}

}
